<?php
namespace Commons;

use GuzzleHttp\Client as HttpClient;

class Http
{
    private static $client;

    public function __construct()
    {
    }

    /**
     * @param        $url
     * @param string $method
     * @param array  $params
     * @param int    $timeout
     * @param array  $extHeaders
     *
     * @return mixed|\Psr\Http\Message\ResponseInterface|\Psr\Http\Message\StreamInterface
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public static function request(
        $url,
        $method = "GET",
        $params = [],
        $timeout = 30,
        $extHeaders = [
            'content-type' => 'application/x-www-form-urlencoded',
        ]
    ) {
        $headers      = (array)$extHeaders;
        self::$client = new HttpClient([
            'headers' => $headers,
            'timeout' => $timeout
        ]);
        $method       = strtoupper($method);
        switch ($method) {
            case 'POST':
                if (!empty($params)) {
                    $params = is_array($params) ? $params : http_build_query($params);
                }
                $response = self::$client->request("POST", $url, $params);
                break;
            case 'GET':
                if (!empty($params)) {
                    $url = $url . (strpos($url, '?') ? '&' : '?') . (is_array($params) ? http_build_query($params) : $params);
                }
                $response = self::$client->request("GET", $url);
                break;
        }
        if ($response->getStatusCode() == 200) {
            $body = $response->getBody()->getContents();
            if (!empty($body) && $body[0] == '{') {
                return json_decode($body, true);
            }
            return $response->getBody();
        }
        return false;
    }

    /**
     * @param       $url
     * @param       $file
     * @param array $data
     * @param int   $timeout
     *
     * @return bool|mixed|\Psr\Http\Message\ResponseInterface
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public static function upload($url, $file, $data = [], $timeout = 30)
    {
        self::$client = new HttpClient([
            'timeout' => $timeout
        ]);
        $body         = fopen($file, 'r');
        $response     = self::$client->request('POST', $url, array_merge_recursive(['body' => $body, 'name' => is_array($data) && isset($data['name']) ? $data['name'] : ((is_string($data)) ? $data : '')]));
        if ($response->getStatusCode() == 200) {
            return $response;
        }
        return false;
    }

    /**
     * @param        $url
     * @param string $method
     * @param        $savePathPrefix
     * @param        $saveUrlPath
     * @param int    $timeout
     *
     * @return array
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public static function download($url, $method = "GET", $savePathPrefix, $saveUrlPath, $timeout = 60)
    {
        self::$client = new HttpClient([
            'timeout' => $timeout
        ]);
        $response     = self::$client->request($method, $url);
        if ($response->getStatusCode() == 200) {
            if ($response == '') {
                throw new \Exception('系统错误，下载的文件为空！');
            }
            $dir            = date('ym');
            $savePathPrefix = rtrim($savePathPrefix, '/') . '/' . $dir . '/';
            $saveUrlPath    = rtrim($saveUrlPath, '/') . '/' . $dir . '/';
            if (!file_exists($savePathPrefix)) {
                if (!mkdir($savePathPrefix)) {
                    throw new \Exception('系统错误，上传目录不存在！');
                }
            }
            if (is_dir($savePathPrefix) === false) {
                throw new \Exception('系统错误，上传目录不存在！');
            }
            if (is_writable($savePathPrefix) === false) {
                throw new \Exception('系统错误，上传目录权限错误！');
            }
            $ext      = strtoupper(ltrim(strrchr($response->getHeaders(['content_type']), '/'), '/'));
            $newName  = date("dHis") . mt_rand(10, 99) . '.' . $ext;
            $savePath = $savePathPrefix . $newName;
            $saveUrl  = $saveUrlPath . $newName;
            $fileSize = file_put_contents($savePath, $response->getBody()->getContents());
            if ($fileSize > 0) {
                return [
                    'save_path' => $savePath,
                    'save_url'  => $saveUrl,
                    'file_size' => $fileSize
                ];
            }
            throw new \Exception('系统错误，保存文件失败！');
        }
        throw new \Exception('系统错误,访问Url失败');
    }

}
